package cos.android.voleysplash.level;

import cos.android.voleysplash.element.Element;

public class Motor {

	public static void colision(Element element, Element keyElement) {

		if (element.isDinamicElement() || keyElement.isDinamicElement()) {
			if (colisionPolygonPolygon(element, keyElement)) {

			}
		}

	}

	private static boolean colisionPolygonPolygon(Element element,
			Element keyElement) {

		double minDistance = 9999;
		double deeper = 0;
		Point p1 = null;

		for (Point arista : keyElement.getAristas()) {

			if (element.collition(arista)) {

				for (int i = 0; i < element.getAristas().size() - 1; i++) {

					double aux = Motor.pointLineDistance(arista, element
							.getAristas().elementAt(i), element.getAristas()
							.elementAt(i + 1));
					if (aux < minDistance) {
						minDistance = aux;
					}
				}

				if (minDistance > deeper) {
					p1 = arista;
				}
			}
		}
		if (p1 != null) {
			reaction(keyElement, element, p1);
			element.setLastHitted(keyElement);
			keyElement.setLastHitted(element);
			return true;

		}

		for (Point arista : element.getAristas()) {

			if (keyElement.collition(arista)) {

				for (int i = 0; i < keyElement.getAristas().size() - 1; i++) {

					double aux = Motor.pointLineDistance(arista, keyElement
							.getAristas().elementAt(i), keyElement.getAristas()
							.elementAt(i + 1));
					if (aux < minDistance) {
						minDistance = aux;
					}
				}

				if (minDistance > deeper) {
					p1 = arista;
				}
			}
		}
		if (p1 != null) {
			reaction(keyElement, element, p1);
			keyElement.setLastHitted(element);
			element.setLastHitted(keyElement);
			return true;

		}
		return false;
	}

	private static void reaction(Element keyElement, Element element,
			Point arista) {

		if (element.isPolygon()) {
			element.dispose();
		}
		
		
		
		
		/*
		double minDistance = 9999;
		int p1 = 0;
		for (int i = 0; i < element.getAristas().size() - 1; i++) {

			double aux = Motor.pointLineDistance(arista, element.getAristas()
					.elementAt(i), element.getAristas().elementAt(i + 1));
			if (aux < minDistance) {
				minDistance = aux;
				p1 = i;

			}
		}

		Point point1 = element.getAristas().elementAt(p1);
		Point point2 = element.getAristas().elementAt(p1 + 1);

		float previousSpeedx = 0;
		float previousSpeedy = 0;

		double m2 = 0;
		if (keyElement.getoX() == 0) {
			m2 = Math.atan2(0, 1);
		} else {
			m2 = Math.atan(keyElement.getoX() / keyElement.getoY());
		}

		double m = 0;
		if (point1.getxPos() - point2.getxPos() == 0) {
			previousSpeedx = (float) (-keyElement.getoX());
			previousSpeedy = (float) (-keyElement.getoY());
		} else if (point1.getyPos() - point2.getyPos() == 0) {

			previousSpeedx = (float) (keyElement.getoX());
			previousSpeedy = (float) (keyElement.getoY());

		} else {

			m = Math.atan2((point2.getyPos() - point1.getyPos()),
					(point2.getxPos() - point1.getxPos()));

			previousSpeedx = (float) ((keyElement.getSpeed() + element
					.getSpeed()) * Math.sin(m + m2));
			previousSpeedy = (float) ((keyElement.getSpeed() + element
					.getSpeed()) * Math.cos(m + m2));
		}

		if (keyElement.isDinamicElement()) {
			keyElement.setxPos((float) (keyElement.getxPos() - Math.sin(m)
					* minDistance));
			keyElement.setyPos((float) (keyElement.getyPos() - Math.cos(m)
					* minDistance));
		}
		if (element.isDinamicElement()) {
			element.setxPos((float) (element.getxPos() - Math.sin(m)
					* minDistance));
			element.setyPos((float) (element.getyPos() - Math.cos(m)
					* minDistance));
		}

		keyElement.reset();

		keyElement.applySpeed(previousSpeedx, -previousSpeedy);

		element.applySpeed(-previousSpeedx, previousSpeedy);

		if (Math.abs(keyElement.getoY()) < 40) {
			keyElement.resetY();
		}

		if (Math.abs(element.getoY()) < 40) {
			element.resetY();
		}
*/
	}

	public static double circleLineDistance(Element circle, Point point1,
			Point point2) {

		if (point1.getxPos() - point2.getxPos() == 0) {
			return (Math.min(
					circlePointDistance(circle, point1) - circle.getRadius(),
					circlePointDistance(circle, point2) - circle.getRadius()));
		} else {
			double m = ((point1.getyPos() - point2.getyPos()) / (point1
					.getxPos() - point2.getxPos()));

			double b = point1.getyPos() - m * point1.getxPos();
			double aux = (Math.abs(m * circle.getCenterX()
					- circle.getCenterY() + b))
					/ (Math.sqrt(Math.pow(m, 2) + 1));
			double distance = aux - circle.getRadius();
			return distance;
		}
	}

	public static double circlePointDistance(Element circle, Point point) {

		return Math.sqrt(Math.pow(circle.getCenterX() - point.getxPos(), 2)
				+ Math.pow(circle.getCenterY() - point.getyPos(), 2));

	}

	public static double pointLineDistance(Point point, Point point1,
			Point point2) {
		if (point1.getxPos() - point2.getxPos() == 0) {
			return (pointPointDistance(point,
					new Point(point1.getxPos(), point.getyPos())));
		} else {
			double m = ((point1.getyPos() - point2.getyPos()) / (point1
					.getxPos() - point2.getxPos()));

			double b = point1.getyPos() - m * point1.getxPos();
			double aux = (Math.abs(m * point.getxPos() - point.getyPos() + b))
					/ (Math.sqrt(Math.pow(m, 2) + 1));
			double distance = aux;
			return distance;
		}
	}

	public static double pointPointDistance(Point point1, Point point2) {
		return Math.sqrt(Math.pow(point1.getxPos() - point2.getxPos(), 2)
				+ Math.pow(point1.getyPos() - point2.getyPos(), 2));

	}

}
